package com.zhangxu.microservice.system.biz.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zhangxu.microservice.common.context.EmployeeContextHolder;
import com.zhangxu.microservice.common.exception.BizException;
import com.zhangxu.microservice.common.utils.AssertUtils;
import com.zhangxu.microservice.common.utils.ListUtils;
import com.zhangxu.microservice.system.biz.convert.RoleConverter;
import com.zhangxu.microservice.system.biz.dto.ApplicationDTO;
import com.zhangxu.microservice.system.biz.dto.CreateRoleDTO;
import com.zhangxu.microservice.system.biz.dto.RoleDTO;
import com.zhangxu.microservice.system.biz.dto.UpdateRoleDTO;
import com.zhangxu.microservice.system.biz.service.ApplicationService;
import com.zhangxu.microservice.system.biz.service.RoleService;
import com.zhangxu.microservice.system.dao.condition.RoleCondition;
import com.zhangxu.microservice.system.dao.entity.RoleDO;
import com.zhangxu.microservice.system.dao.enums.RoleStatusEnum;
import com.zhangxu.microservice.system.dao.service.RoleDao;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 角色服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class RoleServiceImpl implements RoleService {

    private final RoleDao roleDao;
    private final RoleConverter roleConverter;
    private final ApplicationService applicationService;

    @Override
    public Long createRole(CreateRoleDTO createRoleDTO) {
        // 检查角色编码在同一应用内是否已存在
        RoleDO existingRole = roleDao.getByAppIdAndCode(createRoleDTO.getAppId(), createRoleDTO.getCode());
        if (existingRole != null) {
            throw new BizException("角色编码在该应用内已存在");
        }

        // 转换并保存角色
        RoleDO roleDO = roleConverter.toRoleDO(createRoleDTO);
        roleDO.setStatus(RoleStatusEnum.INIT);
        roleDO.setCreateBy(EmployeeContextHolder.get().getId());
        roleDao.save(roleDO);
        return roleDO.getId();
    }

    @Override
    public void updateRole(UpdateRoleDTO updateRoleDTO) {
        // 检查角色是否存在
        RoleDO existingRole = roleDao.getById(updateRoleDTO.getId());
        AssertUtils.notNull(existingRole, "角色不存在");
        AssertUtils.isTrue(RoleStatusEnum.INIT.equals(existingRole.getStatus()), "当前状态不能编辑");

        // 转换并更新角色
        RoleDO roleDO = roleConverter.toRoleDO(updateRoleDTO);
        roleDO.setUpdateBy(EmployeeContextHolder.get().getId());
        roleDao.updateById(roleDO);
    }

    @Override
    public void deleteRole(Long roleId) {
        // 检查角色是否存在
        RoleDO existingRole = roleDao.getById(roleId);
        AssertUtils.notNull(existingRole, "角色不存在");
        AssertUtils.isTrue(RoleStatusEnum.INIT.equals(existingRole.getStatus()), "当前状态不能删除");
        // 逻辑删除角色
        RoleDO roleDO = new RoleDO();
        roleDO.setId(roleId);
        roleDO.setDeleteTime(System.currentTimeMillis());
        roleDO.setUpdateBy(EmployeeContextHolder.get().getId());
        roleDao.updateById(roleDO);
    }

    @Override
    public void enableRole(Long roleId) {
        // 检查角色是否存在
        RoleDO existingRole = roleDao.getById(roleId);
        AssertUtils.notNull(existingRole, "角色不存在");
        AssertUtils.isFalse(RoleStatusEnum.ENABLE.equals(existingRole.getStatus()), "当前状态不能启用");

        // 启用角色
        RoleDO roleDO = new RoleDO();
        roleDO.setId(roleId);
        roleDO.setStatus(RoleStatusEnum.ENABLE);
        roleDO.setUpdateBy(EmployeeContextHolder.get().getId());
        roleDao.updateById(roleDO);
    }

    @Override
    public void disableRole(Long roleId) {
        // 检查角色是否存在
        RoleDO existingRole = roleDao.getById(roleId);
        AssertUtils.notNull(existingRole, "角色不存在");
        AssertUtils.isTrue(RoleStatusEnum.ENABLE.equals(existingRole.getStatus()), "当前状态不能停用");

        // 禁用角色
        RoleDO roleDO = new RoleDO();
        roleDO.setId(roleId);
        roleDO.setStatus(RoleStatusEnum.DISABLE);
        roleDO.setUpdateBy(EmployeeContextHolder.get().getId());
        roleDao.updateById(roleDO);
    }

    @Override
    public RoleDTO getRoleById(Long roleId) {
        RoleDO roleDO = roleDao.getById(roleId);
        return roleDO != null ? roleConverter.toRoleDTO(roleDO) : null;
    }


    @Override
    public IPage<RoleDTO> rolePage(RoleCondition condition) {
        IPage<RoleDO> rolePage = roleDao.page(condition);
        //查询系统名称
        List<RoleDO> records = rolePage.getRecords();
        if (CollUtil.isNotEmpty(records)) {
            Set<Long> appIds = ListUtils.mapSet(records, RoleDO::getAppId);
            List<ApplicationDTO> applicationDTOS = applicationService.listApplicationByIds(appIds);
            Map<Long, ApplicationDTO> appMap = ListUtils.toMap(applicationDTOS, ApplicationDTO::getId);
            return rolePage.convert(record -> {
                RoleDTO roleDTO = roleConverter.toRoleDTO(record);
                ApplicationDTO applicationDTO = appMap.get(record.getAppId());
                roleDTO.setAppName(applicationDTO.getName());
                roleDTO.setAppCode(applicationDTO.getCode());
                return roleDTO;
            });
        }
        return rolePage.convert(roleConverter::toRoleDTO);
    }
}